#pragma once

#include <string>
#include <vector>

struct js_event;

namespace Lijol
{

/*
	https://www.kernel.org/doc/Documentation/input/joystick-api.txt

	It seems that:
	- on horizontal axes, left is negative, right is positive
	- on vertical axes, up is negative, bottom is positive (inverted compared to Windows)
*/
class Joystick
{
public:
	Joystick( const char* device );
	virtual ~Joystick();
	bool					isValid() const;

	const std::string&		getDeviceName() const				{ return mDeviceName; }
    int						getDriverVersion() const            { return mDriverVersion; }
    const std::string&		getName() const						{ return mName; }


    std::size_t				getNumAxes() const                  { return mAxisValues.size(); }
	short int				getAxisValue( std::size_t axisIndex ) const;	// Returns the axis value in the range [-32767..32767]

    std::size_t				getNumButtons() const               { return mButtonValues.size(); }
    bool					getButtonValue( std::size_t buttonIndex ) const;

    bool					update();		// Returns false if the joystick couldn't be read (device wasn't opened, or closed abruptly, etc...)

    std::string				toString() const;
	
protected:
	friend class JoystickManager;
	static bool				getJoystickInfo( int handle, int& driverVersion, std::string& name, char& numAxes, char& numButtons );
    bool        		    processEvents();
    void        		    processEvent( const js_event& event );
    void        		    setAxisValue( std::size_t axisIndex, short int value );
    void        		    setButtonValue( std::size_t buttonIndex, bool value );

private:
	std::string				mDeviceName;
    int                     mJoystickHandle;
    int                     mDriverVersion;
    std::string             mName;
    std::vector<short int>  mAxisValues;
    std::vector<bool>       mButtonValues;
};

}
